#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QHostAddress>
#include <QUdpSocket>
#include <QTime>
#include <QDebug>
#include "vector"
#include <iostream>
#include <QMessageBox>

QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    QUdpSocket *udpSocket;

    QString host = "";
    qint16 port = 0;//远程主机端口
    QHostAddress local_ip;
    quint16 local_port=0;//本机端口
    bool isConnected=false;

    //通过QDatastream组装成数据帧
typedef struct
{
    unsigned int head=0x55555555;//索引 0x55555555
    unsigned int count;         //计数
    unsigned int command;       //命令字	=1使能；=2回零；=3定位指令；=4插入指令；=5退出指令；=6急停；=7复位；=8停止运动；=9继续运动；=10对准
    unsigned int subCommand;    //=1绝对定位；=2相对定位；
    unsigned int subCommand2;   //=1基座坐标；=2平台坐标
    float x;					//目标位姿（相对平台坐标偏移量）
    float y;
    float z;
    float roll;
    float yaw;
    float pitch;
    unsigned int tail=0xaaaaaaaa;//AAAAAAAA
}SEND_TO_PLC;


    //接收后通过QDatastream拆解
typedef struct
{
    unsigned int head=0x66666666;//索引 0x66666666
    unsigned int count;			//计数
    unsigned int status;		//状=0 未启动； =1 初始化中； =2 初始化完成； =3 回零中； =4 已到零位； =5 负载定位中； =6 负载插入中； =7 负载安装到位； =8 平台退出中； =9急停； =10伺服故障；=11角度到软限位，指令无法下发;=12 杆长到软限位;=13停止运动;=14触发硬限位;=15对准中;=16对准完成;=17弯矩或力过大停止运动
    unsigned int subStatus1;
    unsigned int subStatus2;
    unsigned int subStatus3;
    unsigned int subStatus4;

    float x;					//当前位姿
    float y;
    float z;
    float roll;
    float yaw;
    float pitch;
    float l1;					//当前杆长
    float l2;
    float l3;
    float l4;
    float l5;
    float l6;
    float sensor1;				//传感器值
    float sensor2;
    float sensor3;
    unsigned int servoErr[6];
    float torque[6];//扭矩
    unsigned int tail=0x88888888;		//88888888
}RECEIVE_FROM_PLC;

    int times=0;

    double check(SEND_TO_PLC);

    QByteArray serializeFrame(SEND_TO_PLC);

    //模拟下为系统向上位机发送数据
    QByteArray test2(RECEIVE_FROM_PLC);

    void readData(QDataStream& in, float &f)
    {
        //写操作需要引用！！！
        in.setFloatingPointPrecision(QDataStream::SinglePrecision);
        in >> f;
    }

    //mainwindow.cpp文件中无法使用
    RECEIVE_FROM_PLC deserializeFrame(QByteArray& data)
    {
        RECEIVE_FROM_PLC frame;
        QDataStream stream(data);
//        qDebug()<<"data"<<data;
        stream.setByteOrder(QDataStream::BigEndian);
        stream>>frame.head>>frame.count>>frame.status>>frame.subStatus1>>frame.subStatus2>>frame.subStatus3>>frame.subStatus4;

        readData(stream,frame.x);
        readData(stream,frame.y);
        readData(stream,frame.z);
        readData(stream,frame.roll);
        readData(stream,frame.yaw);
        readData(stream,frame.pitch);

        readData(stream,frame.l1);
        readData(stream,frame.l2);
        readData(stream,frame.l3);
        readData(stream,frame.l4);
        readData(stream,frame.l5);
        readData(stream,frame.l6);

        readData(stream,frame.sensor1);
        readData(stream,frame.sensor2);
        readData(stream,frame.sensor3);


        for (int i=0;i<6;i++) {
            stream>>frame.servoErr[i];
        }
        for (int i=0;i<6;i++) {
            readData(stream,frame.torque[i]);
        }
        stream>>frame.tail;
        return frame;
    }

    int param_mode=0;

    bool stop=false;

    float b=0;

private slots:

    void readMsg();

    void on_clear_clicked();

    void on_input_clicked();

    void on_motor_on_clicked();

    void on_self_check_clicked();

    void on_internet_connect_clicked();

    void on_internet_disconnect_clicked();

    void on_input_max_clicked();

    void on_stop_clicked();

    void on_pushButton_clicked();

    void writeReal(QDataStream& out, float f);


    void on_continue_2_clicked();

    void on_mode_absolute_toggled(bool checked);

    void on_mode_relative_toggled(bool checked);

private:
    Ui::MainWindow *ui;

};
#endif // MAINWINDOW_H
